#include "config.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <unistd.h>
#include <libgen.h>
#include <cstring>
#include <glib.h>

// Global configuration variable definition
BaseConfig baseConfig;

// Global variables for function key configuration
std::map<std::string, std::map<std::string, std::string>> config;

// Helper function to trim whitespace from both ends of a string
std::string trim(const std::string& str) {
    const std::string whitespace = " \t\r\n";
    size_t start = str.find_first_not_of(whitespace);
    if (start == std::string::npos) {
        return "";
    }
    size_t end = str.find_last_not_of(whitespace);
    return str.substr(start, end - start + 1);
}

// Helper function to convert string to lowercase
std::string toLower(const std::string& str) {
    std::string result = str;
    std::transform(result.begin(), result.end(), result.begin(), ::tolower);
    return result;
}

// Function to parse a configuration file and return key-value pairs
std::map<std::string, std::string> parseConfigFile(const std::string& configFile) {
    std::map<std::string, std::string> configMap;
    std::ifstream file(configFile);
    
    if (!file.is_open()) {
        std::cerr << "无法打开配置文件: " << configFile << std::endl;
        return configMap;
    }
    
    std::string line;
    std::string currentSection;
    
    while (std::getline(file, line)) {
        // Remove leading/trailing whitespace
        line = trim(line);
        
        // Skip empty lines and comments
        if (line.empty() || line[0] == '#' || line[0] == ';') {
            continue;
        }
        
        // Check for section header
        if (line[0] == '[' && line[line.size() - 1] == ']') {
            currentSection = line.substr(1, line.size() - 2);
            continue;
        }
        
        // Parse key=value pairs
        size_t equalPos = line.find('=');
        if (equalPos != std::string::npos) {
            std::string key = trim(line.substr(0, equalPos));
            std::string value = trim(line.substr(equalPos + 1));
            
            // If we're in a section, prefix the key with the section name
            if (!currentSection.empty()) {
                key = currentSection + "." + key;
            }
            
            configMap[key] = value;
        }
    }
    
    file.close();
    return configMap;
}

// Function to load base configuration from file
bool loadBaseConfig(const std::string& configFile) {
    std::string configPath;
    
    // Load config file directly from the config directory relative to the executable
    char* execPath = g_file_read_link("/proc/self/exe", NULL);
    char* configFilePath = nullptr;
    
    if (execPath) {
        char* execDir = g_path_get_dirname(execPath);
        // If configFile already contains "config/" prefix, don't add it again
        if (configFile.find("config/") == 0) {
            configFilePath = g_build_filename(execDir, configFile.c_str(), NULL);
        } else {
            configFilePath = g_build_filename(execDir, "config", configFile.c_str(), NULL);
        }
        g_free(execDir);
        g_free(execPath);
    }
    
    bool configFound = false;
    if (configFilePath) {
        std::ifstream file(configFilePath);
        if (file.is_open()) {
            configPath = configFilePath;
            configFound = true;
            std::cout << "找到基础配置文件: " << configPath << std::endl;
            file.close();
        } else {
            std::cerr << "无法打开基础配置文件: " << configFilePath << std::endl;
        }
        g_free(configFilePath);
    }
    
    if (!configFound) {
        std::cerr << "无法找到基础配置文件: " << configFile << std::endl;
        return false;
    }
    
    // Parse the configuration file
    std::map<std::string, std::string> configMap = parseConfigFile(configPath);
    
    // Load serial port configuration
    if (configMap.find("SerialPort.Port") != configMap.end()) {
        baseConfig.port = configMap["SerialPort.Port"];
    } else {
        baseConfig.port = "/dev/ttyUSB0";  // Default value
    }
    
    if (configMap.find("SerialPort.BaudRate") != configMap.end()) {
        try {
            baseConfig.baudRate = std::stoi(configMap["SerialPort.BaudRate"]);
        } catch (...) {
            baseConfig.baudRate = 9600;  // Default value
        }
    } else {
        baseConfig.baudRate = 9600;  // Default value
    }
    
    if (configMap.find("SerialPort.StopBits") != configMap.end()) {
        try {
            baseConfig.stopBits = std::stoi(configMap["SerialPort.StopBits"]);
        } catch (...) {
            baseConfig.stopBits = 1;  // Default value
        }
    } else {
        baseConfig.stopBits = 1;  // Default value
    }
    
    if (configMap.find("SerialPort.DataBits") != configMap.end()) {
        try {
            baseConfig.dataBits = std::stoi(configMap["SerialPort.DataBits"]);
        } catch (...) {
            baseConfig.dataBits = 8;  // Default value
        }
    } else {
        baseConfig.dataBits = 8;  // Default value
    }
    
    if (configMap.find("SerialPort.Parity") != configMap.end()) {
        baseConfig.parity = configMap["SerialPort.Parity"];
    } else {
        baseConfig.parity = "None";  // Default value
    }
    
    if (configMap.find("SerialPort.FlowControl") != configMap.end()) {
        baseConfig.flowControl = configMap["SerialPort.FlowControl"];
    } else {
        baseConfig.flowControl = "None";  // Default value
    }
    
    // Load radio configuration
    if (configMap.find("RadioConfig.CurrentBand") != configMap.end()) {
        baseConfig.currentBand = configMap["RadioConfig.CurrentBand"];
    } else {
        baseConfig.currentBand = "20";  // Default value
    }
    
    if (configMap.find("RadioConfig.CurrentFrequency") != configMap.end()) {
        try {
            baseConfig.currentFrequency = std::stod(configMap["RadioConfig.CurrentFrequency"]);
        } catch (...) {
            baseConfig.currentFrequency = 14023.0;  // Default value
        }
    } else {
        baseConfig.currentFrequency = 14023.0;  // Default value
    }
    
    if (configMap.find("RadioConfig.WPM") != configMap.end()) {
        try {
            baseConfig.wpm = std::stoi(configMap["RadioConfig.WPM"]);
            // Ensure WPM is within valid range
            if (baseConfig.wpm < 5) baseConfig.wpm = 5;
            if (baseConfig.wpm > 40) baseConfig.wpm = 40;
        } catch (...) {
            baseConfig.wpm = 15;  // Default value
        }
    } else {
        baseConfig.wpm = 15;  // Default value
    }
    
    std::cout << "成功加载基础配置文件: " << configPath << std::endl;
    return true;
}

// Function to save base configuration to file
bool saveBaseConfig(const std::string& configFile) {
    // Save config file directly to the config directory relative to the executable
    char* execPath = g_file_read_link("/proc/self/exe", NULL);
    char* configFilePath = nullptr;
    
    if (execPath) {
        char* execDir = g_path_get_dirname(execPath);
        // If configFile already contains "config/" prefix, don't add it again
        if (configFile.find("config/") == 0) {
            configFilePath = g_build_filename(execDir, configFile.c_str(), NULL);
        } else {
            configFilePath = g_build_filename(execDir, "config", configFile.c_str(), NULL);
        }
        g_free(execDir);
        g_free(execPath);
    }
    
    std::ofstream file(configFilePath ? configFilePath : configFile);
    if (!file.is_open()) {
        std::cerr << "无法创建或写入配置文件: " << (configFilePath ? configFilePath : configFile) << std::endl;
        if (configFilePath) g_free(configFilePath);
        return false;
    }
    
    if (configFilePath) g_free(configFilePath);
    
    file << "[SerialPort]\n";
    file << "Port=" << baseConfig.port << "\n";
    file << "BaudRate=" << baseConfig.baudRate << "\n";
    file << "StopBits=" << baseConfig.stopBits << "\n";
    file << "DataBits=" << baseConfig.dataBits << "\n";
    file << "Parity=" << baseConfig.parity << "\n";
    file << "FlowControl=" << baseConfig.flowControl << "\n";
    file << "\n";
    file << "[RadioConfig]\n";
    file << "CurrentBand=" << baseConfig.currentBand << "\n";
    file << "CurrentFrequency=" << baseConfig.currentFrequency << "\n";
    file << "WPM=" << baseConfig.wpm << "\n";
    
    file.close();
    std::cout << "成功保存配置文件: " << configFile << std::endl;
    return true;
}